#
# base.mk: base make-file
#
# CopyRight (c) ACLINK
#
# Revision:
#    2010-07-13: zhousw create
#

# ------------------------------------
#     variable describe
# ------------------------------------
# TARGET		output file (.o, .a, .rel)
# SRC			  source file(s)
# INCDIRS		header file search path, using by #include <...>
# DEFINES		flags
# CFLAGS		c/c++ defined flags
# SUBDIRS		to build a list of subdirectories
#

# ------------------------------------
#     debug value
# ------------------------------------
ifneq "$(origin DEBUG)" "undefined"
  ifeq "$(strip $(DEBUG))" ""
    override DEBUG = 1
  endif
  export DEBUG
endif

# ------------------------------------
#     command define
# ------------------------------------
CXX     := $(PREFIX)g++
CC      := $(PREFIX)gcc
AS      := $(PREFIX)as
AR      := $(PREFIX)ar
LD      := $(PREFIX)ld
OBJCOPY := $(PREFIX)objcopy
STRIP   := $(PREFIX)strip
RANLIB  := $(PREFIX)ranlib
RM      := rm -f
MKDIR   := mkdir -p
CAT     := cat

# ------------------------------------
#     error output file
# ------------------------------------
ERROUT_FILE ?= $(basename $@).txt
_CAT_ERROUT_FILE  = $(CAT) $(ERROUT_FILE);
_CAT_WARNOUT_FILE = $(CAT) $(ERROUT_FILE);

# ------------------------------------
#     output dir
# ------------------------------------
OUTDIR  ?= .

# ------------------------------------
#     variables
# ------------------------------------
MAKEFILE ?= Makefile		# make file

# defines/flags
ALWAYS_DEFINES =
ALWAYS_FLAGS   =

# POSIX defined
ALWAYS_DEFINES += __USE_GNU
ALWAYS_DEFINES += _POSIX_THREAD_PRIORITY_SCHEDULING

# c flags
ALWAYS_FLAGS   += -Wall

# byte-endian
#ALWAYS_FLAGS   += -EL
ALWAYS_DEFINES += __LITTLE_ENDIAN__

# debug symbols
ALWAYS_FLAGS   += -g

# ar flags
ARFLAGS = rv

# ld flags
LDFLAGS = -Ur
ifeq "-EL" "$(findstring -EL,$(ALWAYS_FLAGS))"
  LDFLAGS += -EL
endif
ifeq "-EB" "$(findstring -EB,$(ALWAYS_FLAGS))"
  LDFLAGS += -EB
endif

# objcopy flags
OBJCOPYFLAGS = -S

# collect flags/defines
ALWAYS_DEFINES+= $(DEFINES)
ALL_CFLAGS    += $(CFLAGS) $(CCFLAGS)

INCLUDE_LIST  := $(foreach dir,$(INCDIRS),-I$(dir))
DEFINE_LIST   := $(foreach dir,$(ALWAYS_DEFINES),-D$(dir))
OBJS          := $(addsuffix .o,$(basename $(SRC)))
DEPENDENCIES  := $(OBJS:.o=.d)
_TARGET       := $(TARGET)
ifneq ($(strip $(_TARGET)),)
  _TARGET := $(OUTDIR)/$(_TARGET)
endif

# ------------------------------------
#     rule
# ------------------------------------
.PHONY: all subdirs clean dclean

# ------------------------------------
#     default target
# ------------------------------------
ifeq ($(strip $(SUBDIRS)),)
all: $(_TARGET)
else
all: subdirs $(_TARGET)
endif

# ------------------------------------
#     clean
# ------------------------------------
clean:: subdirs
ifneq ($(strip $(SRC)), )
	-@$(RM) $(OBJS) $(DEPENDENCIES) $(OBJS:.o=.txt) $(OBJS:.o=.lst)
endif
ifneq ($(strip $(_TARGET)),)
	-@$(RM) $(_TARGET)
endif

$(OUTDIR)::
	@test -d $(OUTDIR) || $(MKDIR) $(OUTDIR)

# ------------------------------------
#     library
# ------------------------------------
ifneq ($(strip $(OBJS)), )
$(OUTDIR)/%.a: $(OBJS) $(MAKEFILE)
	@echo "===== archive $@"
	-$(RM) $@
	$(AR) $(ARFLAGS) $@ $(OBJS)
	$(RANLIB) $@
endif

ifneq ($(strip $(OBJS)),)
$(OUTDIR)/%.rel: $(OBJS)
	@echo "===== incremental link $@"
	$(LD) $(LDFLAGS) -o $@ $(OBJS)
endif

$(OUTDIR)/%.o $(OUTDIR)/%.d: %.c
	@echo ""
	@echo "===== compile $<  ($@: $?)"
	@test -d $(@D) || $(MKDIR) $(@D)
	$(CC) $(ALL_CPPFLAGS) $(ALWAYS_FLAGS) $(ALL_CFLAGS) $(INCLUDE_LIST) \
    $(DEFINE_LIST) -MD -c -o $(basename $@).o $< 2> $(ERROUT_FILE) || { $(_CAT_ERROUT_FILE) false; }
	@if [ -s $(ERROUT_FILE) ]; then $(_CAT_WARNOUT_FILE) else  $(RM) $(ERROUT_FILE); fi

$(OUTDIR)/%.o $(OUTDIR)/%.d: %.s
	$(compile_s)

$(OUTDIR)/%.o $(OUTDIR)/%.d: %.S
	$(compile_s)

ALL_SUBDIRS = $(SUBDIRS) nulldir

subdirs:
	@for i in ${ALL_SUBDIRS}; do \
		if [ "$$i" != "nulldir" -a -d $$i ]; then \
			${MAKE} -C $$i ${MAKEDEFS} ${MAKECMDGOALS} || exit 1; \
		fi \
	done

# ------------------------------------
#     depend objects
# ------------------------------------
ifneq ($(MAKECMDGOALS),clean)
  ifneq ($(MAKECMDGOALS),dclean)
    ifneq ($(strip $(DEPENDENCIES)),)
      -include $(DEPENDENCIES)
    endif
  endif
endif

# EOF
